﻿using System;
using System.Globalization;
using System.Xml.Linq;

namespace Red.Core.Extensions
{
    public static class Xml
    {
        /// <summary>
        /// Add attribute to xml node
        /// </summary>
        /// <remarks>
        /// Attribute ignored if invalid parameters are specified
        /// </remarks>
        /// <returns><see langword="true"/> if attribute was successfully added to the node, otherwise <see langword="false"/></returns>
        /// <seealso cref="GetAttribute"/>
        public static bool AddAttribute( this XElement element, XName name, object value )
        {
            if ( !string.IsNullOrEmpty( name.LocalName ) && value != null )
            {
                XAttribute attr = new XAttribute( name, value );
                element.Add( attr );

                return true;
            }

            return false;
        }

        /// <summary>
        /// Get the value of a particular attribute
        /// </summary>
        /// <returns>The value of the specified attribute as a <see langword="string"/>. <see langword="null"/> if not found</returns>
        /// <seealso cref="AddAttribute"/>
        public static T GetAttribute<T>( this XElement element, XName name ) where T : IConvertible
        {
            if ( !string.IsNullOrEmpty( name.LocalName ) )
            {
                XAttribute attribute = element.Attribute( name );

                if ( attribute != null )
                {
                    // The XML schema spec specifies that floating point numbers are represented using a period and not using a comma. The locale doesn't have any affect on what is valid XML.
                    // http://www.w3.org/TR/xmlschema-2/#decimal
                    // Hopefully this means we can just use InvariantCulture and hope for the best
                    return (T)Convert.ChangeType( attribute.Value, typeof( T ), CultureInfo.InvariantCulture );
                }
            }

            return default( T );
        }
    }
}
